home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / mordor_2.000 / mordor_2 / src / magic1.c < prev    next >
C/C++ Source or Header  |  1995-06-21  |  26KB  |  935 lines

  1. /*
  2.  * MAGIC1.C:
  3.  *
  4.  *  User routines dealing with magic spells.  Potions, wands,
  5.  *  scrolls, and casting are all covered.
  6.  *
  7.  *  Copyright (C) 1991, 1992, 1993 Brett J. Vickers
  8.  *
  9.  */
  10.  
  11. #include "mstruct.h"
  12. #include "mextern.h"
  13.  
  14. /**********************************************************************/
  15. /*              cast                      */
  16. /**********************************************************************/
  17.  
  18. /* This function allows a player to cast a magical spell.  It looks at */
  19. /* the second parsed word to find out if the spell-name is valid, and  */
  20. /* then calls the appropriate spell function.                  */
  21.  
  22. int cast(ply_ptr, cmnd)
  23. creature    *ply_ptr;
  24. cmd     *cmnd;
  25. {
  26.     long    i, t, z, chance;
  27.     int (*fn)();
  28.     int fd, splno, c = 0, match = 0, n;
  29.  
  30.     fd = ply_ptr->fd;
  31.  
  32.     if(cmnd->num < 2) {
  33.         print(fd, "Cast what?\n");
  34.         return(0);
  35.     }
  36.     if(F_ISSET(ply_ptr, PBLIND)) {
  37.     ANSI(fd, RED);
  38.     print(fd, "You can't see to direct the incantation!\n");
  39.     ANSI(fd, WHITE);
  40.     return(0);
  41.     }
  42.     if(F_ISSET(ply_ptr, PSILNC)) {
  43.     ANSI(fd, YELLOW);
  44.     print(fd, "You can't recite the incantation!\n");
  45.     ANSI(fd, WHITE);
  46.     return(0);
  47.     }
  48.     do {
  49.         if(!strcmp(cmnd->str[1], spllist[c].splstr)) {
  50.             match = 1;
  51.             splno = c;
  52.             break;
  53.         }
  54.         else if(!strncmp(cmnd->str[1], spllist[c].splstr, 
  55.             strlen(cmnd->str[1]))) {
  56.             match++;
  57.             splno = c;
  58.         }
  59.         c++;
  60.     } while(spllist[c].splno != -1);
  61.  
  62.     if(match == 0) {
  63.         print(fd, "That spell does not exist.\n");
  64.         return(0);
  65.     }
  66.  
  67.     else if(match > 1) {
  68.         print(fd, "Spell name is not unique.\n");
  69.         return(0);
  70.     }
  71.  
  72.     if(F_ISSET(ply_ptr->parent_rom, RNOMAG)) {
  73.         print(fd, "Nothing happens.\n");
  74.         return(0);
  75.     }
  76.  
  77.     i = LT(ply_ptr, LT_SPELL);
  78.     t = time(0);
  79.  
  80.     if(t < i) {
  81.         please_wait(fd, i-t);
  82.         return(0);
  83.     }
  84.  
  85.     F_CLR(ply_ptr, PHIDDN);
  86.  
  87.     fn = spllist[splno].splfn;
  88.  
  89.     if(fn == offensive_spell) {
  90.         for(c=0; ospell[c].splno != spllist[splno].splno; c++)
  91.             if(ospell[c].splno == -1) return(0);
  92.         n = (*fn)(ply_ptr, cmnd, CAST, spllist[splno].splstr,
  93.             &ospell[c]);
  94.     }
  95.  
  96.     else
  97.         n = (*fn)(ply_ptr, cmnd, CAST);
  98.  
  99.     if(n) {
  100.         ply_ptr->lasttime[LT_SPELL].ltime = t;
  101.         if(ply_ptr->class == CLERIC || ply_ptr->class == MAGE)
  102.             ply_ptr->lasttime[LT_SPELL].interval = 3;
  103.         else
  104.             ply_ptr->lasttime[LT_SPELL].interval = 5;
  105.     }
  106.  
  107.     return(0);
  108.  
  109. }
  110.  
  111. /**********************************************************************/
  112. /*              teach                     */
  113. /**********************************************************************/
  114.  
  115. /* This function allows mages to teach other players the first six    */
  116. /* spells.                                */
  117.  
  118. int teach(ply_ptr, cmnd)
  119. creature    *ply_ptr;
  120. cmd     *cmnd;
  121. {
  122.     room        *rom_ptr;
  123.     creature    *crt_ptr;
  124.     int     fd, splno, c = 0, match = 0;
  125.  
  126.     fd = ply_ptr->fd;
  127.     rom_ptr = ply_ptr->parent_rom;
  128.  
  129.     if(cmnd->num < 3) {
  130.         print(fd, "Teach whom what?\n");
  131.         return(0);
  132.     }
  133.     if(F_ISSET(ply_ptr, PBLIND)) {
  134.         ANSI(fd, RED);
  135.         print(fd, "You can't see to do that!\n");
  136.         ANSI(fd, WHITE);
  137.         return(0);
  138.     }
  139.     if(F_ISSET(ply_ptr, PSILNC)) {
  140.     ANSI(fd, YELLOW);
  141.     print(fd, "You can't speak to do that!\n");
  142.     ANSI(fd, WHITE);
  143.     return(0);
  144.     }
  145.  
  146.     if((ply_ptr->class != MAGE && ply_ptr->class != CLERIC) && ply_ptr->class < CARETAKER)  {
  147.         print(fd, "Only mages and clerics may teach spells.\n");
  148.         return(0);
  149.     }
  150.  
  151.     cmnd->str[1][0] = up(cmnd->str[1][0]);
  152.     crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply, cmnd->str[1], 
  153.                cmnd->val[1]);
  154.  
  155.     if(!crt_ptr) {
  156.         print(fd, "I don't see that person here.\n");
  157.         return(0);
  158.     }
  159.  
  160.     do {
  161.         if(!strcmp(cmnd->str[2], spllist[c].splstr)) {
  162.             match = 1;
  163.             splno = c;
  164.             break;
  165.         }
  166.         else if(!strncmp(cmnd->str[2], spllist[c].splstr, 
  167.             strlen(cmnd->str[2]))) {
  168.             match++;
  169.             splno = c;
  170.         }
  171.         c++;
  172.     } while(spllist[c].splno != -1);
  173.  
  174.     if(match == 0) {
  175.         print(fd, "That spell does not exist.\n");
  176.         return(0);
  177.     }
  178.  
  179.     else if(match > 1) {
  180.         print(fd, "Spell name is not unique.\n");
  181.         return(0);
  182.     }
  183.  
  184.     if(!S_ISSET(ply_ptr, spllist[splno].splno)) {
  185.         print(fd, "You don't know that spell.\n");
  186.         return(0);
  187.     }
  188.  
  189.     if((spllist[splno].splno > 3) && (ply_ptr->class != CLERIC && ply_ptr->class < CARETAKER)) {
  190.         print(fd, "You may not teach that spell to anyone.\n");
  191.         return(0);
  192.     }
  193.  
  194.     if((spllist[splno].splno > 5) && (ply_ptr->class != DM)) {
  195.         print(fd, "You may not teach that spell to anyone.\n");
  196.         return(0);
  197.     }
  198.  
  199.     if((spllist[splno].splno < 3) && (ply_ptr->class != MAGE && ply_ptr->class < CARETAKER)) {
  200.         print(fd, "You may not teach that spell to anyone.\n");
  201.         return(0);
  202.     }
  203.    
  204.  
  205.     F_CLR(ply_ptr, PHIDDN);
  206.  
  207.     S_SET(crt_ptr, spllist[splno].splno);
  208.     print(crt_ptr->fd, "%M teaches you the %s spell.\n", ply_ptr,
  209.           spllist[splno].splstr);
  210.     print(fd, "Spell \"%s\" taught to %m.\n", spllist[splno].splstr,
  211.           crt_ptr);
  212.  
  213.     broadcast_rom2(fd, crt_ptr->fd, rom_ptr->rom_num,
  214.                "%M taught %m the %s spell.", ply_ptr, crt_ptr,
  215.                spllist[splno].splstr);
  216.  
  217.     return(0);
  218.  
  219. }
  220.  
  221. /**********************************************************************/
  222. /*              study                     */
  223. /**********************************************************************/
  224.  
  225. /* This function allows a player to study a scroll, and learn the spell */
  226. /* that is on it.                           */
  227.  
  228. int study(ply_ptr, cmnd)
  229. creature    *ply_ptr;
  230. cmd     *cmnd;
  231. {
  232.     object  *obj_ptr;
  233.     int fd, n, match=0;
  234.  
  235.     fd = ply_ptr->fd;
  236.  
  237.     if(cmnd->num < 2) {
  238.         print(fd, "Study what?\n");
  239.         return(0);
  240.     }
  241.     if(F_ISSET(ply_ptr, PBLIND)) {
  242.         ANSI(fd, RED);
  243.         print(fd, "You can't see to do that!\n");
  244.         ANSI(fd, WHITE);
  245.         return(0);
  246.     }
  247.  
  248.     obj_ptr = find_obj(ply_ptr, ply_ptr->first_obj,
  249.                cmnd->str[1], cmnd->val[1]);
  250.  
  251.     if(!obj_ptr || !cmnd->val[1]) {
  252.         for(n=0; n<MAXWEAR; n++) {
  253.             if(!ply_ptr->ready[n]) continue;
  254.             if(EQUAL(ply_ptr->ready[n], cmnd->str[1]))
  255.                 match++;
  256.             else continue;
  257.             if(match == cmnd->val[1] || !cmnd->val[1]) {
  258.                 obj_ptr = ply_ptr->ready[n];
  259.                 break;
  260.             }
  261.         }
  262.     }
  263.  
  264.     if(!obj_ptr) {
  265.         print(fd, "You don't have that.\n");
  266.         return(0);
  267.     }
  268.  
  269.     if(obj_ptr->type != SCROLL) {
  270.         print(fd, "That's not a scroll.\n");
  271.         return(0);
  272.     }
  273.  
  274.     if((F_ISSET(obj_ptr, OGOODO) && ply_ptr->alignment < -100) ||
  275.        (F_ISSET(obj_ptr, OEVILO) && ply_ptr->alignment > 100)) {
  276.         print(fd, "%I burns you and you drop it.\n", obj_ptr);
  277.         del_obj_crt(obj_ptr, ply_ptr);
  278.         add_obj_rom(obj_ptr, ply_ptr->parent_rom);
  279.         return(0);
  280.     }
  281.  
  282.     if (F_ISSET(obj_ptr,OPLDGK) && 
  283.         (BOOL(F_ISSET(obj_ptr,OKNGDM)) != BOOL(F_ISSET(ply_ptr,PKNGDM)))){
  284.         print(fd, "You are unable to use %i.\n",obj_ptr);
  285.         return(0);
  286.     }
  287.  
  288.   if(F_ISSET(obj_ptr,OCLSEL))
  289.         if(!F_ISSET(obj_ptr,OCLSEL + ply_ptr->class) && ( ply_ptr->class < CARETAKER)){
  290.                 print(fd, "Your class prevents you from using %i.\n",obj_ptr);
  291.                 return(0);
  292.         }                 
  293.  
  294.     F_CLR(ply_ptr, PHIDDN);
  295.  
  296.     print(fd, "You learn the %s spell.\n", 
  297.           spllist[obj_ptr->magicpower-1].splstr);
  298.     print(fd, "%I disintegrates!\n", obj_ptr);
  299.     broadcast_rom(fd, ply_ptr->rom_num, "%M studies %1i.",
  300.               ply_ptr, obj_ptr);
  301.  
  302.     S_SET(ply_ptr, obj_ptr->magicpower-1);
  303.     del_obj_crt(obj_ptr, ply_ptr);
  304.     free_obj(obj_ptr);
  305.  
  306.     return(0);
  307.  
  308. }
  309.  
  310. /**********************************************************************/
  311. /*              readscroll                */
  312. /**********************************************************************/
  313.  
  314. /* This function allows a player to read a scroll and cause its magical */
  315. /* spell to be cast.  If a third word is used in the command, then that */
  316. /* player or monster will be the target of the spell.           */
  317.  
  318. int readscroll(ply_ptr, cmnd)
  319. creature    *ply_ptr;
  320. cmd     *cmnd;
  321. {
  322.     object  *obj_ptr;
  323.     int (*fn)();
  324.     long    i, t;
  325.     int fd, n, match=0, c, splno;
  326.  
  327.     fd = ply_ptr->fd;
  328.     fn = 0;
  329.  
  330.     if(cmnd->num < 2) {
  331.         print(fd, "Read what?\n");
  332.         return(0);
  333.     }
  334.     if(F_ISSET(ply_ptr, PBLIND)) {
  335.         ANSI(fd, RED);
  336.         print(fd, "You can't see to do that!\n");
  337.         ANSI(fd, WHITE);
  338.         return(0);
  339.     }
  340.     obj_ptr = find_obj(ply_ptr, ply_ptr->first_obj,
  341.                cmnd->str[1], cmnd->val[1]);
  342.  
  343.     if(!obj_ptr || !cmnd->val[1]) {
  344.         for(n=0; n<MAXWEAR; n++) {
  345.             if(!ply_ptr->ready[n]) continue;
  346.             if(EQUAL(ply_ptr->ready[n], cmnd->str[1]))
  347.                 match++;
  348.             else continue;
  349.             if(match == cmnd->val[1] || !cmnd->val[1]) {
  350.                 obj_ptr = ply_ptr->ready[n];
  351.                 break;
  352.             }
  353.         }
  354.     }
  355.  
  356.     if(!obj_ptr) {
  357.         print(fd, "You don't have that.\n");
  358.         return(0);
  359.     }
  360.  
  361.     if(obj_ptr->special) {
  362.         n = special_obj(ply_ptr, cmnd, SP_MAPSC);
  363.         if(n != -2) return(MAX(0, n));
  364.     }
  365.  
  366.     if(obj_ptr->type != SCROLL) {
  367.         print(fd, "That's not a scroll.\n");
  368.         return(0);
  369.     }
  370.  
  371.     if((F_ISSET(obj_ptr, OGOODO) && ply_ptr->alignment < -100) ||
  372.        (F_ISSET(obj_ptr, OEVILO) && ply_ptr->alignment > 100)) {
  373.         print(fd, "%I burns you and you drop it.\n", obj_ptr);
  374.         del_obj_crt(obj_ptr, ply_ptr);
  375.         add_obj_rom(obj_ptr, ply_ptr->parent_rom);
  376.         return(0);
  377.     }
  378.  
  379.     if (F_ISSET(obj_ptr,OPLDGK) &&
  380.         (BOOL(F_ISSET(obj_ptr,OKNGDM)) != BOOL(F_ISSET(ply_ptr,PKNGDM)))){
  381.         print(fd, "You are unable to read %i.\n",obj_ptr);
  382.         return(0);
  383.     }              
  384.  
  385.  
  386.   if(F_ISSET(obj_ptr,OCLSEL))
  387.         if(!F_ISSET(obj_ptr,OCLSEL + ply_ptr->class) && ( ply_ptr->class < CARETAKER)){
  388.                 print(fd, "Your class prevents you from reading %i.\n",obj_ptr);
  389.                 return(0);
  390.         }                 
  391.  
  392.     if(F_ISSET(ply_ptr->parent_rom, RNOMAG) || (obj_ptr->magicpower-1 < 0)) {
  393.         print(fd, "Nothing happens.\n");
  394.         return(0);
  395.     }
  396.  
  397.     i = LT(ply_ptr, LT_READS);
  398.     t = time(0);
  399.  
  400.     if(i > t) {
  401.         please_wait(fd, i-t);
  402.         return(0);
  403.     }
  404.  
  405.     F_CLR(ply_ptr, PHIDDN);
  406.  
  407.     ply_ptr->lasttime[LT_READS].ltime = t;
  408.     ply_ptr->lasttime[LT_READS].interval = 3;
  409.  
  410.     if(spell_fail(ply_ptr)){
  411.         print(fd, "%I disintegrates.\n", obj_ptr);
  412.         del_obj_crt(obj_ptr, ply_ptr);
  413.         free_obj(obj_ptr);
  414.         return(0);
  415.     }
  416.  
  417.     splno = obj_ptr->magicpower-1;
  418.     fn = spllist[splno].splfn;
  419.  
  420.     if(fn == offensive_spell) {
  421.         for(c=0; ospell[c].splno != spllist[splno].splno; c++)
  422.             if(ospell[c].splno == -1) return(0);
  423.         n = (*fn)(ply_ptr, cmnd, SCROLL, spllist[splno].splstr,
  424.             &ospell[c]);
  425.     }
  426.  
  427.     else
  428.         n = (*fn)(ply_ptr, cmnd, SCROLL);
  429.  
  430.     if(n) {
  431.         if(obj_ptr->use_output[0])
  432.             print(fd, "%s\n", obj_ptr->use_output);
  433.  
  434.         print(fd, "%I disintegrates.\n", obj_ptr);
  435.         del_obj_crt(obj_ptr, ply_ptr);
  436.         free_obj(obj_ptr);
  437.     }
  438.  
  439.     return(0);
  440.  
  441. }
  442.  
  443. /**********************************************************************/
  444. /*              drink                     */
  445. /**********************************************************************/
  446.  
  447. /* This function allows players to drink potions, thereby casting any */
  448. /* spell it was meant to contain.                     */
  449.  
  450. int drink(ply_ptr, cmnd)
  451. creature    *ply_ptr;
  452. cmd     *cmnd;
  453. {
  454.     object  *obj_ptr;
  455.     int (*fn)();
  456.     long    i, t;
  457.     int fd, n, match=0, c, splno;
  458.  
  459.     fd = ply_ptr->fd;
  460.     fn = 0;
  461.  
  462.     if(cmnd->num < 2) {
  463.         print(fd, "Drink what?\n");
  464.         return(0);
  465.     }
  466.  
  467.     obj_ptr = find_obj(ply_ptr, ply_ptr->first_obj,
  468.                cmnd->str[1], cmnd->val[1]);
  469.  
  470.     if(!obj_ptr || !cmnd->val[1]) {
  471.         for(n=0; n<MAXWEAR; n++) {
  472.             if(!ply_ptr->ready[n]) continue;
  473.             if(EQUAL(ply_ptr->ready[n], cmnd->str[1]))
  474.                 match++;
  475.             else continue;
  476.             if(match == cmnd->val[1] || !cmnd->val[1]) {
  477.                 obj_ptr = ply_ptr->ready[n];
  478.                 break;
  479.             }
  480.         }
  481.     }
  482.  
  483.     if(!obj_ptr) {
  484.         print(fd, "You don't have that.\n");
  485.         return(0);
  486.     }
  487.  
  488.     if(obj_ptr->type != POTION) {
  489.         print(fd, "That's not a potion.\n");
  490.         return(0);
  491.     }
  492.  
  493.     if(obj_ptr->shotscur < 1 || (obj_ptr->magicpower-1 < 0)) {
  494.         print(fd, "It's empty.\n");
  495.         return(0);
  496.     }
  497.  
  498.     if(F_ISSET(ply_ptr->parent_rom, RNOPOT)){
  499.         print(fd, "%I starts to evaporates before you drink it.\n",obj_ptr);
  500.         return(0);
  501.     }
  502.     
  503.     if((F_ISSET(obj_ptr, OGOODO) && ply_ptr->alignment < -100) ||
  504.        (F_ISSET(obj_ptr, OEVILO) && ply_ptr->alignment > 100)) {
  505.         print(fd, "%I burns you and you drop it.\n", obj_ptr);
  506.         del_obj_crt(obj_ptr, ply_ptr);
  507.         add_obj_rom(obj_ptr, ply_ptr->parent_rom);
  508.         return(0);
  509.     }
  510.  
  511.     if (F_ISSET(obj_ptr,OPLDGK) &&
  512.         (BOOL(F_ISSET(obj_ptr,OKNGDM)) != BOOL(F_ISSET(ply_ptr,PKNGDM)))){
  513.         print(fd, "You are unable to drink %i.\n",obj_ptr);
  514.         return(0);
  515.     }              
  516.  
  517.  
  518.   if(F_ISSET(obj_ptr,OCLSEL))
  519.         if(!F_ISSET(obj_ptr,OCLSEL + ply_ptr->class) && ( ply_ptr->class < CARETAKER)){
  520.                 print(fd, "Your class prevents you from drinking %i.\n",obj_ptr);
  521.                 return(0);
  522.         }                 
  523.  
  524.     F_CLR(ply_ptr, PHIDDN);
  525.  
  526.     splno = obj_ptr->magicpower-1;
  527.     fn = spllist[splno].splfn;
  528.  
  529.     if(fn == offensive_spell) {
  530.         for(c=0; ospell[c].splno != spllist[splno].splno; c++)
  531.             if(ospell[c].splno == -1) return(0);
  532.         n = (*fn)(ply_ptr, cmnd, POTION, spllist[splno].splstr,
  533.             &ospell[c]);
  534.     }
  535.  
  536.     else
  537.         n = (*fn)(ply_ptr, cmnd, POTION);
  538.  
  539.     if(n) {
  540.         if(obj_ptr->use_output[0])
  541.             print(fd, "%s\n", obj_ptr->use_output);
  542.  
  543.         print(fd, "Potion drank.\n");
  544.         broadcast_rom(fd, ply_ptr->rom_num, "%M drank %1i.", 
  545.                   ply_ptr, obj_ptr);
  546.  
  547.         if(--obj_ptr->shotscur < 1) {
  548.             print(fd, "%I disintegrates.\n", obj_ptr);
  549.             del_obj_crt(obj_ptr, ply_ptr);
  550.             free_obj(obj_ptr);
  551.         }
  552.     }
  553.  
  554.     return(0);
  555.  
  556. }
  557.  
  558. /**********************************************************************/
  559. /*              zap                   */
  560. /**********************************************************************/
  561.  
  562. /* This function allows players to zap a wand or staff at another player */
  563. /* or monster.                               */
  564.  
  565. int zap(ply_ptr, cmnd)
  566. creature    *ply_ptr;
  567. cmd     *cmnd;
  568. {
  569.     object  *obj_ptr;
  570.     long    i, t;
  571.     int fd, n, match=0;
  572.  
  573.     fd = ply_ptr->fd;
  574.  
  575.     if(cmnd->num < 2) {
  576.         print(fd, "Use what?\n");
  577.         return(0);
  578.     }
  579.     if(F_ISSET(ply_ptr, PBLIND)) {
  580.         ANSI(fd, RED);
  581.         print(fd, "You can't see to use that!\n");
  582.         ANSI(fd, WHITE);
  583.         return(0);
  584.     }
  585.  
  586.     obj_ptr = find_obj(ply_ptr, ply_ptr->first_obj,
  587.                cmnd->str[1], cmnd->val[1]);
  588.  
  589.     if(!obj_ptr || !cmnd->val[1]) {
  590.         for(n=0; n<MAXWEAR; n++) {
  591.             if(!ply_ptr->ready[n]) continue;
  592.             if(EQUAL(ply_ptr->ready[n], cmnd->str[1]))
  593.                 match++;
  594.             else continue;
  595.             if(match == cmnd->val[1] || !cmnd->val[1]) {
  596.                 obj_ptr = ply_ptr->ready[n];
  597.                 break;
  598.             }
  599.         }
  600.     }
  601.  
  602.     if(!obj_ptr) {
  603.         print(fd, "You don't have that.\n");
  604.         return(0);
  605.     }
  606.  
  607.     if(obj_ptr->type != WAND) {
  608.         print(fd, "That's not a wand or staff.\n");
  609.         return(0);
  610.     }
  611.  
  612.     if(obj_ptr->shotscur < 1) {
  613.         print(fd, "It's used up.\n");
  614.         return(0);
  615.     }
  616.  
  617.     if((F_ISSET(obj_ptr, OGOODO) && ply_ptr->alignment < -100) ||
  618.        (F_ISSET(obj_ptr, OEVILO) && ply_ptr->alignment > 100)) {
  619.         print(fd, "%I burns you and you drop it.\n", obj_ptr);
  620.         del_obj_crt(obj_ptr, ply_ptr);
  621.         add_obj_rom(obj_ptr, ply_ptr->parent_rom);
  622.         return(0);
  623.     }
  624.  
  625.     if (F_ISSET(obj_ptr,OPLDGK) &&
  626.         (BOOL(F_ISSET(obj_ptr,OKNGDM)) != BOOL(F_ISSET(ply_ptr,PKNGDM)))){
  627.         print(fd, "You are unable to use %i.\n",obj_ptr);
  628.         return(0);
  629.     }              
  630.  
  631.  
  632.   if(F_ISSET(obj_ptr,OCLSEL))
  633.         if(!F_ISSET(obj_ptr,OCLSEL + ply_ptr->class) && ( ply_ptr->class < CARETAKER)){
  634.                 print(fd, "Your class prevents you from using %i.\n",obj_ptr);
  635.                 return(0);
  636.         }                 
  637.  
  638.  
  639.     if(F_ISSET(ply_ptr->parent_rom, RNOMAG) || (obj_ptr->magicpower < 1)) {
  640.         print(fd, "Nothing happens.\n");
  641.         return(0);
  642.     }
  643.  
  644.     i = LT(ply_ptr, LT_SPELL);
  645.     t = time(0);
  646.  
  647.     if(i > t) {
  648.         please_wait(fd, i-t);
  649.         return(0);
  650.     }
  651.  
  652.     F_CLR(ply_ptr, PHIDDN);
  653.  
  654.     ply_ptr->lasttime[LT_SPELL].ltime = t;
  655.     ply_ptr->lasttime[LT_SPELL].interval = 3;
  656.  
  657.     if(spell_fail(ply_ptr)){
  658.         obj_ptr->shotscur--;
  659.         return(0);
  660.     }
  661.  
  662.     return(zap_obj(ply_ptr, obj_ptr, cmnd));
  663. }
  664.  
  665. /************************************************************************/
  666. /*              zap_obj                 */
  667. /************************************************************************/
  668.  
  669. /* This function is a subfunction of zap that accepts a player and  */
  670. /* an object as its parameters.                     */
  671.  
  672. int zap_obj(ply_ptr, obj_ptr, cmnd)
  673. creature    *ply_ptr;
  674. object      *obj_ptr;
  675. cmd     *cmnd;
  676. {
  677.     int splno, c, fd, n;
  678.     int (*fn)();
  679.  
  680.     fd = ply_ptr->fd;
  681.     splno = obj_ptr->magicpower-1;
  682.     if (splno < 0) 
  683.     return(0);
  684.     fn = spllist[splno].splfn;
  685.  
  686.     if(fn == offensive_spell) {
  687.         for(c=0; ospell[c].splno != spllist[splno].splno; c++)
  688.             if(ospell[c].splno == -1) return(0);
  689.         n = (*fn)(ply_ptr, cmnd, WAND, spllist[splno].splstr,
  690.             &ospell[c]);
  691.     }
  692.     else
  693.         if (!F_ISSET(obj_ptr,ODDICE))
  694.             n = (*fn)(ply_ptr, cmnd, WAND);
  695.         else
  696.             n = (*fn)(ply_ptr, cmnd, WAND, obj_ptr);
  697.  
  698.     if(n) {
  699.         if(obj_ptr->use_output[0])
  700.             print(fd, "%s\n", obj_ptr->use_output);
  701.  
  702.         obj_ptr->shotscur--;
  703.     }
  704.  
  705.     return(0);
  706.  
  707. }
  708.  
  709. /************************************************************************/
  710. /*              offensive_spell             */
  711. /************************************************************************/
  712.  
  713. /* This function is called by all spells whose sole purpose is to do    */
  714. /* damage to a given creature.                      */
  715.  
  716. int offensive_spell(ply_ptr, cmnd, how, spellname, osp)
  717. creature    *ply_ptr;
  718. cmd     *cmnd;
  719. int     how;
  720. char        *spellname;
  721. osp_t       *osp;
  722. {
  723.     creature    *crt_ptr;
  724.     room        *rom_ptr;
  725.     int     m, fd, dmg, bns=0;
  726.     long        addrealm;
  727.  
  728.     fd = ply_ptr->fd;
  729.     rom_ptr = ply_ptr->parent_rom;
  730.  
  731.     if(ply_ptr->mpcur < osp->mp && how == CAST) {
  732.         print(fd, "Not enough magic points.\n");
  733.         return(0);
  734.     }
  735.  
  736.     if(!S_ISSET(ply_ptr, osp->splno) && how == CAST) {
  737.         print(fd, "You don't know that spell.\n");
  738.         return(0);
  739.     }
  740.  
  741.  
  742.     if(F_ISSET(ply_ptr, PINVIS)) {
  743.         F_CLR(ply_ptr, PINVIS);
  744.         print(fd, "Your invisibility fades.\n");
  745.         broadcast_rom(fd, ply_ptr->rom_num, "%M fades into view.",
  746.                   ply_ptr);
  747.     }
  748.  
  749.     if(how == CAST) switch(osp->bonus_type) {
  750.     case 1:
  751.         bns = bonus[ply_ptr->intelligence] +
  752.             mprofic(ply_ptr, osp->realm)/10;
  753.         break;
  754.     case 2:
  755.         bns = bonus[ply_ptr->intelligence] +
  756.             mprofic(ply_ptr, osp->realm)/6;
  757.         break;
  758.     case 3:
  759.         bns = bonus[ply_ptr->intelligence] +
  760.             mprofic(ply_ptr, osp->realm)/4;
  761.         break;
  762.     }
  763.  
  764.     if(F_ISSET(rom_ptr, RWATER)) {
  765.         switch(osp->realm) {
  766.         case WATER: bns *= 2; break;
  767.         case FIRE:  bns = MIN(-bns, -5); break;
  768.         }
  769.     }
  770.     else if(F_ISSET(rom_ptr, RFIRER)) {
  771.         switch(osp->realm) {
  772.         case FIRE:  bns *= 2; break;
  773.         case WATER: bns = MIN(-bns, -5); break;
  774.         }
  775.     }
  776.     else if(F_ISSET(rom_ptr, RWINDR)) {
  777.         switch(osp->realm) {
  778.         case WIND:  bns *= 2; break;
  779.         case EARTH: bns = MIN(-bns, -5); break;
  780.         }
  781.     }
  782.     else if(F_ISSET(rom_ptr, REARTH)) {
  783.         switch(osp->realm) {
  784.         case EARTH: bns *= 2; break;
  785.         case WIND:  bns = MIN(-bns, -5); break;
  786.         }
  787.     }
  788.         
  789.     /* Cast on self */
  790.     if(cmnd->num == 2) {
  791.  
  792.         dmg = dice(osp->ndice, osp->sdice, osp->pdice+bns);
  793.         dmg = MAX(1, dmg);
  794.  
  795.         ply_ptr->hpcur -= dmg;
  796.  
  797.         if(how == CAST)
  798.             ply_ptr->mpcur -= osp->mp;
  799.  
  800.         if(how == CAST || how == SCROLL || how == WAND)  {
  801.             print(fd, "You cast a %s spell on yourself.\n",
  802.                 spellname);
  803.             print(fd, "The spell did %d damage.\n", dmg);
  804.             broadcast_rom(fd, ply_ptr->rom_num, 
  805.                       "%M casts a %s spell on %sself.", 
  806.                       ply_ptr, spellname,
  807.                       F_ISSET(ply_ptr, PMALES) ? "him":"her");
  808.         }
  809.         else if(how == POTION) {
  810.             print(fd, "Yuck! That's terrible!\n");
  811.             print(fd, "%d hit points removed.\n", dmg);
  812.         }
  813.  
  814.         if(ply_ptr->hpcur < 1) {
  815.             print(fd, "Don't be stupid.\n");
  816.             ply_ptr->hpcur = 1;
  817.             return(2);
  818.         }
  819.  
  820.     }
  821.  
  822.     /* Cast on monster or player */
  823.     else {
  824.  
  825.         if(how == POTION) {
  826.             print(fd, "You can only use a potion on yourself.\n");
  827.             return(0);
  828.         }
  829.  
  830.         crt_ptr = find_crt(ply_ptr, rom_ptr->first_mon,
  831.                    cmnd->str[2], cmnd->val[2]);
  832.  
  833.         if(!crt_ptr) {
  834.             cmnd->str[2][0] = up(cmnd->str[2][0]);
  835.             crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply,
  836.                        cmnd->str[2], cmnd->val[2]);
  837.  
  838.             if(!crt_ptr || crt_ptr == ply_ptr || 
  839.                strlen(cmnd->str[2]) < 3) {
  840.                 print(fd, "That's not here.\n");
  841.                 return(0);
  842.             }
  843.  
  844.         }
  845.  
  846.         if(crt_ptr->type == MONSTER && F_ISSET(crt_ptr, MUNKIL)) {
  847.             print(fd, "You cannot harm %s.\n",
  848.                 F_ISSET(crt_ptr, MMALES) ? "him":"her");
  849.             return(0);
  850.         }
  851.  
  852.         if(ply_ptr->type == PLAYER && crt_ptr->type == PLAYER &&
  853.             crt_ptr != ply_ptr) {
  854.             if(F_ISSET(rom_ptr, RNOKIL)) {
  855.                 print(fd,"No killing allowed in this room.\n");
  856.                 return;
  857.             }
  858.         if(ply_ptr->level<4 && crt_ptr->level>5){
  859.         print(fd, "That would be foolish.\n");
  860.         return;
  861.         }
  862.             if((!F_ISSET(ply_ptr,PPLDGK) || !F_ISSET(crt_ptr,PPLDGK)) ||
  863.                 (BOOL(F_ISSET(ply_ptr,PKNGDM)) == BOOL(F_ISSET(crt_ptr,PKNGDM))) ||
  864.                 (! AT_WAR)) {
  865.                 if(!F_ISSET(ply_ptr, PCHAOS)) {
  866.                     print(fd, "Sorry, you're lawful.\n");
  867.                     return(0);
  868.                 }
  869.                 if(!F_ISSET(crt_ptr, PCHAOS)) {
  870.                     print(fd, "Sorry, that player is lawful.\n");
  871.                     return(0);
  872.                 }     
  873.             }
  874.         }
  875.     if(crt_ptr->type != MONSTER)    
  876.         if(is_charm_crt(ply_ptr->name, crt_ptr) && F_ISSET(ply_ptr, PCHARM)){
  877.                 print(fd, "You just can't bring yourself to do that.\n");
  878.                 return(0);
  879.                 }
  880.  
  881.         if(how == CAST)
  882.             ply_ptr->mpcur -= osp->mp;
  883.  
  884.     if(spell_fail(ply_ptr)){
  885.             return(0);
  886.         }
  887.  
  888.         dmg = dice(osp->ndice, osp->sdice, osp->pdice+bns);
  889.         dmg = MAX(1, dmg);
  890.  
  891.         if((crt_ptr->type == PLAYER && F_ISSET(crt_ptr, PRMAGI)) ||
  892.            (crt_ptr->type != PLAYER && F_ISSET(crt_ptr, MRMAGI)))
  893.             dmg -= (dmg * 2 *
  894.               MIN(50, crt_ptr->piety + crt_ptr->intelligence)) /
  895.               100;
  896.  
  897.         m = MIN(crt_ptr->hpcur, dmg);
  898.  
  899.         addrealm = (m * crt_ptr->experience) / MAX(1,crt_ptr->hpmax);
  900.         addrealm = MIN(addrealm, crt_ptr->experience);
  901.         if(crt_ptr->type != PLAYER)
  902.             ply_ptr->realm[osp->realm-1] += addrealm;
  903.         if(crt_ptr->type != PLAYER) {
  904.             add_enm_crt(ply_ptr->name, crt_ptr);
  905.             add_enm_dmg(ply_ptr->name, crt_ptr, m);
  906.         }
  907.  
  908.         crt_ptr->hpcur -= dmg;
  909.         if(how == CAST || how == SCROLL || how == WAND) {
  910.             print(fd, "You cast a %s spell on %s.\n", spellname,
  911.                 crt_ptr->name);
  912.             print(fd, "The spell did %d damage.\n", dmg);
  913.             broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num,
  914.                        "%M casts a %s spell on %m.",
  915.                        ply_ptr, spellname, crt_ptr);
  916.             print(crt_ptr->fd, 
  917.                   "%M casts a %s spell on you for %d damage.\n",
  918.                   ply_ptr, spellname, dmg);
  919.         }
  920.  
  921.  
  922.         if(crt_ptr->hpcur < 1) {
  923.             print(fd, "You killed %m.\n", crt_ptr);
  924.             broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num,
  925.                       "%M killed %m.", ply_ptr, crt_ptr);
  926.             die(crt_ptr, ply_ptr);
  927.             return(2);
  928.         }
  929.  
  930.     }
  931.  
  932.     return(1);
  933.  
  934. }
  935.